#include <iostream>
#include <sstream>
#include <string>

using namespace std;

void print_binary_int(int n) {
  size_t len = sizeof(int) * 8;
  bool leading = false;
  for (int i = len-1; i >=0; i--) {
    if (n & 1 << i) {
      cout << 1;
      leading = true;
    }
    else if (leading)
      cout << 0;
  }
  cout << endl;
}

// problem 1
int update_bits(int m, int n, size_t i, size_t j) {
  if (i >= j) 
    throw "i should be smaller than j";

  int max = ~0;
  int right = (1 << i) - 1;
  int left = max - ((1 << j) - 1);
  print_binary_int(left);
  int mask = left | right;
  return (m & mask) | (n << i);
}

// problem 2
void print_binary_float(const string& num) {
  size_t pos = num.find(".");
  int intPart = 0;
  double decPart = 0.0;
  stringstream ss;

  if (pos != string::npos) {
    ss << num.substr(0, pos); ss >> intPart; ss.clear();
    ss << 0 << num.substr(pos); ss >> decPart; ss.clear();
  }
  else {
    ss << num; ss >> intPart; ss.clear();
  }
  
  string intOutput;
  while (intPart) {
    int r = intPart % 2;
    intPart >>= 1;
    intOutput = (char) (r + '0') + intOutput;
  }

  string decOutput;
  const double eps = 1e-12;
  while (decPart > eps) {
    decPart *= 2;
    if (decPart >= 1) {
      decPart -= 1;
      decOutput = decOutput + "1";
    }
    else {
      decOutput = decOutput + "0";
    }
    if (decOutput.size() > 32) {
      cout << "ERROR" << endl;
      return;
    }
  }

  cout << intOutput << "." << decOutput << endl;
}

// problem 3
// not clearly defined. skiped.

// problem 5
size_t bits_to_convert(size_t a, size_t b) {
  size_t cnt = 0;
  int num = a ^ b;
  while (num) {
    num = num & (num - 1);
    cnt++;
  }
  return cnt;
}

// problem 6
size_t swap_bits(size_t n) {
  return ((0xAAAA & n) >> 1) | ((0x5555 & n) << 1);
}

// problem 7
// psudo code. skipped.

int main() {
  cout << "Problem 1: " << endl;
  int m = 1 << 10;
  int n = (1 << 4) + 5;
  print_binary_int(m);
  print_binary_int(n);
  print_binary_int(update_bits(m, n, 2, 6));
  cout << endl;

  cout << "Problem 2: " << endl;
  cout << "Test binary representation of float" << endl;
  print_binary_float("3.75");
  print_binary_float("3.72");
  cout << endl;

  cout << "Problem 3: " << endl;
  cout << endl;

  cout << "Problem 5: " << endl;
  cout << "Number of bits to convert 31 to 14 is: " << bits_to_convert(31, 14) << " == 2" << endl;
  cout << endl;

  cout << "Problem 6: " << endl;
  cout << "Swap odd and even bits" << endl;
  int num = 121;
  print_binary_int(num);
  print_binary_int(swap_bits(num));
  cout << endl;

  return 0;
}
